package com.hdd.art.utils;

import sun.net.util.IPAddressUtil;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 作者： fangzehua
 * 时间： 2021/6/19 15:01
 *
 * @Version: 1.0
 * @Desc 类描述信息
 */
public class IntnetUtil {

    public static final String nei_NET = "nei";
    public static final String wai_NET = "wai";

    /**
     * @Title: isPortStart
     * @Description: 判断端口是否开启
     * @param @param host
     * @param @param port
     * @param @return 设定文件
     * @return boolean 返回类型
     * @throws
     * @date 2015年7月23日 下午1:55:51
     */
    public static boolean isPortStart(String host, int port) {
        Socket socket = null;
        try
        {
            InetAddress theAddress = InetAddress.getByName(host);
            socket = new Socket(theAddress, port);
            return true;
        }
        catch (Exception e)
        {
            return false;
        }
        finally
        {
            try
            {
                if (socket != null)
                {
                    socket.close();
                    socket = null;
                }
            }
            catch (Exception e)
            {

            }
        }
    }

    /**
     * 获取客户端真实ip地址
     *
     * @description
     * @param request
     * @return
     * @author
     * @date 2010-3-31
     * @history
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("x-forwarded-for");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     *
     * @Title: checkIpAddr
     * @Description: ip比对方法
     * @param @param http_ips
     * @param @param auth_ip
     * @param @return 设定文件
     * @return boolean 返回类型
     * @throws
     * @date 2020年3月31日 下午4:36:12
     */
    public static boolean checkIpAddr(String http_ips, String auth_ip){
        String ipsStr = StringUtil.NullToString(auth_ip);
        if (ipsStr.trim().equals("*")) return true;
        boolean ok = false;
        for (String ip : http_ips.split(","))
        {
            if (ipOK(ip, ipsStr)) ok = true;
            if (ok) break;
        }
        return ok;
    }

    /**
     * @Title: ipOK
     * @Description: 判断ip是否符合规则
     * @param @param
     *        http_ip
     * @param @param
     *        ipsStr
     * @param @return
     *        设定文件
     * @return boolean 返回类型
     * @throws
     * @date
     *       2018年3月14日 下午5:36:41
     */
    private static boolean ipOK(String http_ip, String ipsStr) {
        String[] ips = ipsStr.split(",");
        for (String ip : ips)
        {
            if (http_ip.trim().startsWith(ip.trim().replaceAll("\\*.*", "").replaceAll("\\*", ""))) return true;
        }
        return false;
    }

    /**
     * @Title: getHostNameForLiunx
     * @Description: 获取机器名
     * @param @return 设定文件
     * @return String 返回类型
     * @throws
     * @date 2016年5月24日 上午9:54:52
     */
    public static String getHostNameForLiunx() {
        try
        {
            return (InetAddress.getLocalHost()).getHostName();
        }
        catch (UnknownHostException uhe)
        {
            String host = uhe.getMessage(); // host = "hostname: hostname"
            if (host != null)
            {
                int colon = host.indexOf(':');
                if (colon > 0) { return host.substring(0, colon); }
            }
            return "UnknownHost";
        }
    }

    /**
     * @Title: getHostIpForLiunx
     * @Description: 获取内外网信息
     * @param @return 设定文件
     * @return Map<String,List<String>> 返回类型
     * @throws
     * @date 2019年7月29日 下午6:18:42
     */
    public static Map<String, List<String>> getHostIpForLiunx() {
        String def = "127.0.0.1";
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        try
        {
            List<String> nei = new ArrayList<String>();
            List<String> wai = new ArrayList<String>();
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements())
            {
                NetworkInterface ni = interfaces.nextElement();
                Enumeration<InetAddress> addresss = ni.getInetAddresses();
                while (addresss.hasMoreElements())
                {
                    String hostAddress = addresss.nextElement().getHostAddress();
                    System.out.println(hostAddress);
                    if (isIp(hostAddress))
                    {
                        if (internalIp(IPAddressUtil.textToNumericFormatV4(hostAddress)))
                        {
                            //内网
                            nei.add(hostAddress);
                        }
                        else
                        {
                            //外网
                            if (!hostAddress.equals(def)) wai.add(hostAddress);
                        }
                    }
                }
            }
            if (nei.isEmpty()) nei.add(def);
            map.put(nei_NET, nei);
            map.put(wai_NET, wai);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * @Title: internalIp
     * @Description: 是内网ip
     * @param @param ip
     * @param @return 设定文件
     * @return boolean 返回类型
     * @throws
     * @date 2017年3月13日 下午1:50:33
     */
    public static boolean internalIp(String ip) {
        if (!isIp(ip)) return false;
        return internalIp(IPAddressUtil.textToNumericFormatV4(ip));
    }

    /**
     * 判断是否为合法IP格式
     *
     * @return the ip
     */
    public static boolean isIp(String ipAddress) {
        String ip = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}";
        Pattern pattern = Pattern.compile(ip);
        Matcher matcher = pattern.matcher(ipAddress);
        return matcher.matches();
    }

    /**
     * @Title: internalIp
     * @Description: 判断是否是内网ip
     * @param @param addr
     * @param @return 设定文件
     * @return boolean 返回类型
     * @throws
     * @date 2019年7月29日 下午6:19:43
     */
    public static boolean internalIp(byte[] addr) {
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        //A类 10.0.0.0--10.255.255.255
        final byte SECTION_1 = 0x0A;
        //B类 172.16.0.0--172.31.255.255
        final byte SECTION_2 = (byte) 0xAC;
        final byte SECTION_3 = (byte) 0x10;
        final byte SECTION_4 = (byte) 0x1F;
        //C类 192.168.0.0--192.168.255.255
        final byte SECTION_5 = (byte) 0xC0;
        final byte SECTION_6 = (byte) 0xA8;
        switch (b0) {
            case SECTION_1:
                return true;
            case SECTION_2:
                if (b1 >= SECTION_3 && b1 <= SECTION_4) { return true; }
            case SECTION_5:
                switch (b1) {
                    case SECTION_6:
                        return true;
                }
            default:
                return false;
        }
    }

    /**
     * @Title: dubboBindIp
     * @Description: dubbo绑定指定网段ip
     * @param @param map
     * @param @param notAllowIps
     * @param @return 设定文件
     * @return String 返回类型
     * @throws
     * @date 2020年3月18日 上午9:39:37
     */
    public static String dubboBindIp(Map<String, List<String>> map, String notAllowIps) {
        if (StringUtil.isEmpty(notAllowIps)) return null;
        List<String> list = map.get(nei_NET);
        for (String ip : list)
        {
            String[] cips = notAllowIps.split(",");
            for (String cip : cips)
            {
                if (ip.trim().startsWith(cip.trim().replaceAll("\\*.*", "").replaceAll("\\*", "")))
                {
                    return ip;
                }
                else
                {
                    continue;
                }
            }
        }
        return null;
    }
}